package net.ming616.nlp.hit.service.impl;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.PostConstruct;

import net.ming616.nlp.common.model.NLPWord;
import net.ming616.nlp.common.model.SRLNode;
import net.ming616.nlp.hit.service.HITManager;
import net.ming616.nlp.hit.utils.LTPUtils;

import org.apache.log4j.Logger;
import org.jdom.JDOMException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import edu.hit.ir.ltpService.LTML;
import edu.hit.ir.ltpService.LTPOption;
import edu.hit.ir.ltpService.LTPService;
import edu.hit.ir.ltpService.SRL;
import edu.hit.ir.ltpService.Word;

@Service("hitManager")
public class HitManagerImpl implements HITManager {
	/**
	 * Logger for this class
	 */
	private static final Logger logger = Logger.getLogger(HitManagerImpl.class);

	LTPService ls;

	@Value("${ltp.password}")
	String password;

	@Value("${ltp.username}")
	String username;

	public LTML analyze(List<String> words) throws JDOMException, IOException {
		LTML ltml = new LTML();
		ltml.clear();
		ArrayList<Word> ltpWords = new ArrayList<Word>();
		for (int i = 0; i < words.size(); i++) {
			Word ltpWord = new Word();
			ltpWord.setID(i);
			ltpWord.setWS(words.get(i));
			ltpWords.add(ltpWord);
		}
		ltml.addSentence(ltpWords, 0);
		LTML result = this.ls.analyze(LTPOption.ALL, ltml);
		if (logger.isInfoEnabled()) {
			logger.info("analyze(List<String>) - LTML result=" + result); //$NON-NLS-1$
		}
		return result;
	}

	public LTML analyze(String sentence) throws JDOMException, IOException {
		LTML result = null;
		result = ls.analyze(LTPOption.ALL, sentence);
		return result;
	}

	public List<Map<String, String>> analyzeToMap(String question)
			throws JDOMException, IOException {
		LTML ltml = this.analyze(question);
		int sentNum = ltml.countSentence();
		List<Map<String, String>> result = new ArrayList<Map<String, String>>();
		for (int i = 0; i < sentNum; ++i) {
			ArrayList<Word> wordList = ltml.getWords(i);
			for (Word word : wordList) {
				Map<String, String> map = LTPUtils.convertWordToMap(word);
				result.add(map);
			}
		}
		return result;
	}

	public String analyzeToString(String question) throws JDOMException,
			IOException {
		LTML ltml = this.analyze(question);
		int sentNum = ltml.countSentence();
		// List<Map<String, String>> result = new ArrayList<Map<String,
		// String>>();
		StringBuffer buffer = new StringBuffer();
		for (int i = 0; i < sentNum; ++i) {
			ArrayList<Word> wordList = ltml.getWords(i);
			for (Word word : wordList) {
				String wordString = LTPUtils.converWordToString(word);
				buffer.append(wordString + " ");
			}
		}
		return buffer.toString();
	}

	@PostConstruct
	private void init() {
		logger.info("username=" + this.username + ",password=" + this.password);
		ls = new LTPService(this.username + ":" + this.password);
		ls.setEncoding(LTPOption.UTF8);
	}

	public List<NLPWord> parse(List<NLPWord> sentence) {
		LTML ltml = new LTML();
		ltml.clear();
		ArrayList<Word> ltpWords = new ArrayList<Word>();
		for (int j = 0; j < sentence.size(); j++) {
			NLPWord word = sentence.get(j);
			Word ltpWord = new Word();
			ltpWord.setID(j);
			ltpWord.setWS(word.getText());
			ltpWords.add(ltpWord);
		}
		LTML result = null;
		try {
			ltml.addSentence(ltpWords, 0);
			result = this.ls.analyze(LTPOption.ALL, ltml);
			if (null != result) {
				ArrayList<Word> LTPWords = result.getWords(0);
				for (int j = 0; j < LTPWords.size(); j++) {
					NLPWord nlpWord = sentence.get(j);
					Word ltpword = LTPWords.get(j);
					nlpWord.setNe(ltpword.getNE());
					nlpWord.setWsd(ltpword.getWSD());
					nlpWord.setParent(ltpword.getParserParent());
					nlpWord.setRelate(ltpword.getParserRelation());
					nlpWord.setPredicate(ltpword.isPredicate());
					if (nlpWord.isPredicate()) {
						ArrayList<SRL> srls = ltpword.getSRLs();
						for (SRL srl : srls) {
							SRLNode srlNode = new SRLNode();
							srlNode.setBegin(srl.beg);
							srlNode.setEnd(srl.end);
							srlNode.setType(srl.type);
							nlpWord.getSrls().add(srlNode);
						}
					}
				}
			}
		} catch (Exception e) {
			logger.error(e.getMessage());
		}
		return sentence;
	}
}
